home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** File: Help.c
- ** Written by: Eric Soldan
- **
- ** Copyright © 1993 Apple Computer, Inc.
- ** All rights reserved.
- */
-
- /* You may incorporate this sample code into your applications without
- ** restriction, though the sample code has been provided "AS IS" and the
- ** responsibility for its operation is 100% yours. However, what you are
- ** not permitted to do is to redistribute the source as "DSC Sample Code"
- ** after having made changes. If you're going to re-distribute the source,
- ** we require that you make it clear in the source that the code was
- ** descended from Apple Sample Code, but that you've made changes. */
-
- /* This file contains some sample code for handling dynamic balloon help. The
- ** assumption here is that you used the AppsToGo program editor to add controls
- ** to the content of a window that have balloon help assigned to them. */
-
-
-
- /*****************************************************************************/
-
-
-
- #ifndef __BALLOONS__
- #include <Balloons.h>
- #endif
-
- #ifndef __PROCESSES__
- #include <Processes.h>
- #endif
-
- #ifndef __STRING__
- #include <String.h>
- #endif
-
- #ifndef __STDDEF__
- #include <StdDef.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __UTILITIES__
- #include "Utilities.h"
- #endif
-
- typedef struct {
- short helpVers;
- long options;
- short procID;
- short variantForTip;
- short numMessages;
- short itemSize;
- short itemType[];
- } hrctRec;
- typedef hrctRec *hrctRecPtr, **hrctRecHndl;
-
-
-
- /*****************************************************************************/
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- Boolean ControlBalloonHelp(WindowPtr window, Point mouseLoc)
- {
- WindowPtr oldPort;
- ProcessSerialNumber cpsn, fpsn;
- Point tip;
- ControlHandle ctl, cc;
- short i, pos, hrctID, itemID, charsUsed, strNumID, strNumIndx;
- long ofst;
- Boolean procsSame;
- ControlStyleInfo cinfo;
- HMMessageRecord message;
- Rect messageRct, rct;
- hrctRecHndl hrct;
- char *cptr;
- Ptr ptr;
- static HMMessageRecord lastMessage;
- static Rect lastMessageRct;
- static short position[4] = {5, 6, 2, 1};
-
- if (gSystemVersion < 0x0700) return(false);
- /* The system can't support balloons. */
-
- if (!window) {
- if (lastMessage.hmmHelpType)
- HMRemoveBalloon();
- lastMessage.hmmHelpType = 0;
- return(false);
- }
-
- if (!HMGetBalloons()) {
- lastMessage.hmmHelpType = 0;
- return(false);
- } /* Balloons have been turned off. */
-
- HMGetBalloonWindow(&oldPort);
- if (!oldPort)
- lastMessage.hmmHelpType = 0;
- /* There is no balloon currently, so there is no last message. */
-
- tip = mouseLoc;
- GetCurrentProcess(&cpsn);
- GetFrontProcess(&fpsn);
- SameProcess(&cpsn, &fpsn, &procsSame);
- if (!procsSame) {
- lastMessage.hmmHelpType = 0;
- return(false);
- } /* We aren't the front process, so leave. */
-
- if (!GetWRefCon(window)) {
- lastMessage.hmmHelpType = 0;
- return(false);
- }
-
- GetPort(&oldPort);
- SetPort(window);
- GlobalToLocal(&mouseLoc);
- SetPort(oldPort);
-
- ctl = nil;
- cc = ((WindowPeek)window)->controlList;
- while (cc) { /* Find the control that we are over. */
- if (GetControlStyle(cc, &cinfo)) {
- messageRct = (*cc)->contrlRect;
- rct = (*(window->visRgn))->rgnBBox;
- SectRect(&rct, &messageRct, &rct);
- if (PtInRect(mouseLoc, &rct))
- ctl = cc;
- }
- cc = (*cc)->nextControl;
- }
-
- message.hmmHelpType = 0;
- if (ctl) {
- messageRct = (*ctl)->contrlRect;
- GetControlStyle(ctl, &cinfo);
- cptr = (char *)cinfo.balloonHelp;
- p2c((StringPtr)cptr);
- if (!(hrctID = c2dec(cptr, &charsUsed))) {
- lastMessage.hmmHelpType = 0;
- return(false);
- }
- cptr += (charsUsed + 1);
- if (!(hrct = (hrctRecHndl)GetResource('hrct', hrctID))) {
- lastMessage.hmmHelpType = 0;
- return(false);
- }
- if (!(itemID = c2dec(cptr, &charsUsed))) {
- lastMessage.hmmHelpType = 0;
- return(false);
- }
- if (itemID > (*hrct)->numMessages) {
- lastMessage.hmmHelpType = 0;
- return(false);
- }
- cptr += (charsUsed + 1);
- if ((*ctl)->contrlHilite == 255) /* If control inactive... */
- if (i = c2dec(cptr, &charsUsed)) /* If alternate item for inactive... */
- itemID = i; /* Use alternate item. */
- ofst = offsetof(hrctRec,itemSize);
- for (i = 1; i < itemID; ++i) {
- ptr = (Ptr)*hrct;
- ofst += *(short *)(ptr + ofst);
- }
- ofst += sizeof(short); /* Point to item type. */
-
- memset(&message, 0, sizeof(message)); /* Clean out structure for compare purposes. */
- ptr = (Ptr)*hrct;
- message.hmmHelpType = *(short *)(ptr + ofst);
- ofst += sizeof(short);
- ofst += (sizeof(Point) + sizeof(Rect)); /* Skip 'hrct' tip and rect. */
- switch (message.hmmHelpType) {
- case kHMStringItem:
- pcpy((StringPtr)message.u.hmmString, (StringPtr)(ptr + ofst));
- break;
- case kHMPictItem:
- message.u.hmmPict = *(short *)(ptr + ofst);
- break;
- case kHMStringResItem:
- strNumID = *(short *)(ptr + ofst);
- ofst += sizeof(short);
- strNumIndx = *(short *)(ptr + ofst);
- message.u.hmmStringRes.hmmResID = strNumID;
- message.u.hmmStringRes.hmmIndex = strNumIndx;
- break;
- case kHMTEResItem:
- message.u.hmmTERes = *(short *)(ptr + ofst);
- break;
- case kHMSTRResItem:
- message.u.hmmSTRRes = *(short *)(ptr + ofst);
- break;
- }
-
- LocalToGlobalRect(&messageRct);
- pos = (tip.v > (messageRct.top + messageRct.bottom) / 2) ? 2 : 0;
- if (tip.h > (messageRct.left + messageRct.right) / 2)
- ++pos;
- pos = position[pos];
- }
-
- if (message.hmmHelpType) {
- if (!EqualRect(&lastMessageRct, &messageRct))
- lastMessage.hmmHelpType;
- if (!EqualData(&lastMessage, &message, sizeof(message))) { /* If new balloon... */
- HMShowBalloon(&message, tip, &messageRct, nil, 0, pos, kHMRegularWindow);
- lastMessageRct = messageRct;
- lastMessage = message;
- }
- return(true);
- }
-
- return(false);
- }
-
-
-
-